package frame;

import chainOfResponsibility.BulletTankCollider;
import gameBasics.PropertyManager;
import gameLevel.GameLevel;
import gameLevel.GameLevelControl;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Objects;

/**
 * 游戏主窗口
 */
public class MainGameFrame extends GameFrame{

    private int primaryMenuIndex = 0;      //一级菜单索引
    private int secondMenuIndex = 0;       //二级菜单索引
    private enum primaryMenuType {UN_SHOW_MENU, SHOW_MENU ,RUN, HELP, ABOUT}  //一级菜单类型
    private enum secondMenuType {UN_SHOW_MENU, SHOW_MENU, CLASSIC, SURVIVAL}            //二级菜单类型
    private primaryMenuType primaryMenuState = primaryMenuType.SHOW_MENU;               //一级菜单选中状态
    private secondMenuType secondMenuState = secondMenuType.UN_SHOW_MENU;               //二级菜单选中状态
    private final String[] PRIMARY_MENU = {"开始游戏", "游戏帮助", "游戏关于", "退出游戏"};    //主窗口一级菜单(主菜单)
    private final String[] SECONDARY_MENU = {"经典模式", "生存模式"};                       //主窗口二级菜单(游戏模式)
    private final int DISTANCE = Objects.requireNonNull(PropertyManager.getInt("distance"));    //菜单行(字符串)间距
    private final int STR_WIDTH = Objects.requireNonNull(PropertyManager.getInt("strWidth"));   //菜单行(字符串)宽度
    private final int MENU_X = GAME_WIDTH - STR_WIDTH >> 1;    //菜单字符串绘制的x坐标
    private final int MENU_Y = GAME_HEIGHT / 3;                //菜单字符串绘制的y坐标

    /**
     * 单例模式
     */
    private MainGameFrame(){
        super();

        addKeyListener(new MyKeyListener());    //添加键盘监听事件
    }

    private static class MainGameFrameHolder{
        private final static MainGameFrame INSTANCE = new MainGameFrame();
    }

    public static MainGameFrame getInstance(){
        return MainGameFrameHolder.INSTANCE;
    }

    /**
     * 绘制游戏主窗口
     * @param graphics the specified Graphics window
     */
    @Override
    public void paint(Graphics graphics) {
        if(primaryMenuState != primaryMenuType.UN_SHOW_MENU)
        {
            switch (primaryMenuState)
            {
                //显示一级菜单
                case SHOW_MENU ->
                        drawMenu(graphics, PRIMARY_MENU, primaryMenuIndex);
                //开始游戏
                case RUN ->
                {
                    secondMenuState = secondMenuType.SHOW_MENU;
                    primaryMenuState = primaryMenuType.UN_SHOW_MENU;
                }
                //游戏帮助
                case HELP ->
                {
                    String[] strings = new String[]{"↑ ↓ ← →: 控制主坦克方向", "Enter: 选中菜单选项", "Space: 主坦克开火", "Esc: 返回菜单主界面"};
                    for(int i = 0; i < strings.length; i++){
                        drawInformation(graphics, strings[i], GAME_WIDTH - 240 >> 1, GAME_HEIGHT / 3 + DISTANCE * i);
                    }
                }
                //游戏关于
                case ABOUT -> drawInformation(graphics, "开发日期: 12/25-12/30", GAME_WIDTH - 240 >> 1, GAME_HEIGHT / 2);
            }
        }else if(secondMenuState != secondMenuType.UN_SHOW_MENU)
        {
            switch (secondMenuState)
            {
                //显示二级菜单
                case SHOW_MENU ->
                        drawMenu(graphics, SECONDARY_MENU, secondMenuIndex);
                //经典模式
                case CLASSIC ->
                {
                    switch (GameLevelControl.nowClassicGameLevel)
                    {
                        case CLASSIC_LEVE1 -> GameLevelControl.gameLevel = GameLevel.CLASSIC_LEVE1;
                        case CLASSIC_LEVE2 -> GameLevelControl.gameLevel = GameLevel.CLASSIC_LEVE2;
                        case CLASSIC_LEVE3 -> GameLevelControl.gameLevel = GameLevel.CLASSIC_LEVE3;
                        case CLASSIC_LEVE4 -> GameLevelControl.gameLevel = GameLevel.CLASSIC_LEVE4;
                    }

                    gameModel.paint(graphics);
                }
                //生存模式
                case SURVIVAL ->
                {
                    GameLevelControl.gameLevel = GameLevel.SURVIVAL;
                    gameModel.paint(graphics);
                }
            }
        }
    }

    /**
     * 绘制字符串信息
     * @param graphics 画笔对象
     * @param content 字符串对象
     * @param drawX 绘制x坐标
     * @param drawY 绘制y坐标
     */
    private void drawInformation(Graphics graphics, String content, int drawX, int drawY) {
        Color color = graphics.getColor();
        graphics.setColor(Color.WHITE);
        graphics.setFont(new Font("宋体", Font.BOLD, 22));
        graphics.drawString(content, drawX, drawY);
        graphics.setColor(color);
    }

    /**
     * 绘制菜单
     * @param graphics 画笔对象
     * @param menu 菜单对象(实质为String数组)
     * @param menuIndex 菜单索引
     */
    private void drawMenu(Graphics graphics, String[] menu, int menuIndex){
        Color color = graphics.getColor();
        graphics.setFont(new Font("宋体", Font.BOLD, 22));
        for(int i = 0; i < menu.length; i++){
            if(menuIndex == i){
                graphics.setColor(Color.GRAY);  //选中的菜单项的颜色设置为灰色
            }else{
                graphics.setColor(Color.WHITE);
            }
            graphics.drawString(menu[i], MENU_X, MENU_Y + DISTANCE * i);
        }

        graphics.setColor(Color.WHITE);
        graphics.setFont(new Font("宋体", Font.PLAIN, 16));
        graphics.drawString("by:Henu 李子昊", GAME_WIDTH - 120 >> 1, MENU_Y + DISTANCE * 7);
        graphics.setColor(color);
    }

    class MyKeyListener extends KeyAdapter{
        //键盘抬起时调用
        @Override
        public void keyReleased(KeyEvent e) {
            int key = e.getKeyCode();

            switch (key){
                //下键
                case KeyEvent.VK_DOWN -> {
                    if(primaryMenuState != primaryMenuType.UN_SHOW_MENU){
                        if(primaryMenuIndex >= 0 && primaryMenuIndex < PRIMARY_MENU.length - 1) primaryMenuIndex++;
                    }else if(secondMenuState != secondMenuType.UN_SHOW_MENU){
                        if(secondMenuIndex >= 0 && secondMenuIndex < SECONDARY_MENU.length - 1) secondMenuIndex++;
                    }
                }
                //上键
                case KeyEvent.VK_UP -> {
                    if(primaryMenuState != primaryMenuType.UN_SHOW_MENU){
                        if(primaryMenuIndex > 0 && primaryMenuIndex <= PRIMARY_MENU.length - 1) primaryMenuIndex--;
                    }else if(secondMenuState != secondMenuType.UN_SHOW_MENU){
                        if(secondMenuIndex > 0 && secondMenuIndex <= SECONDARY_MENU.length - 1) secondMenuIndex--;
                    }
                }
                //回车键
                case KeyEvent.VK_ENTER -> {
                    if(primaryMenuState != primaryMenuType.UN_SHOW_MENU){
                        switch (primaryMenuIndex){
                            case 0 -> primaryMenuState = primaryMenuType.RUN;
                            case 1 -> primaryMenuState = primaryMenuType.HELP;
                            case 2 -> primaryMenuState = primaryMenuType.ABOUT;
                            case 3 -> System.exit(0);
                        }
                    }else if(secondMenuState != secondMenuType.UN_SHOW_MENU){
                        switch (secondMenuIndex){
                            case 0 -> secondMenuState = secondMenuType.CLASSIC;
                            case 1 -> secondMenuState = secondMenuType.SURVIVAL;
                        }
                    }
                }
                //Esc键
                case KeyEvent.VK_ESCAPE -> {
                    primaryMenuState = primaryMenuType.SHOW_MENU;
                    secondMenuState = secondMenuType.UN_SHOW_MENU;
                    resetGameLevelControl();
                }
            }
        }
    }

    /**
     * 重置GameLevelControl中的控制变量
     */
    private void resetGameLevelControl(){
        GameLevelControl.passState = false;                          //重置关卡通过状态为未通过
        GameLevelControl.gameOverState = false;                      //重置游戏是否结束的状态为false(未开始或尚在游戏中为false)
        GameLevelControl.chooseLevelState = false;                   //重置关卡选中状态为未选中
        BulletTankCollider.resetTheNumOfEnemyTank();                 //重置经典关卡中敌人坦克的数量
    }

}